import tkinter as tk
import random
from tkinter import ttk, messagebox
import pygame
import os

class GobangAI:
    def __init__(self):
        os.chdir(os.path.dirname(os.path.abspath(__file__)))

        self.window = tk.Tk()
        self.window.title("五子棋-人机对战")
        self.window.geometry("700x800")
        self.window.configure(bg='#F0F0F0')
        self.window.option_add('*Font', ('微软雅黑', 12))
        
        # 初始化pygame音频模块
        pygame.mixer.init()
        # 加载音效文件
        self.checker_sound = pygame.mixer.Sound("CheckerSound.mp3")

        # 初始化游戏组件
        self.create_control_panel()
        self.create_game_board()
        self.init_game()
        
        self.window.mainloop()

    def create_control_panel(self):
        """创建顶部控制面板"""
        control_frame = tk.Frame(self.window, bg='#F0F0F0', padx=10, pady=10)
        control_frame.pack(fill=tk.X)
        
        # 新游戏按钮
        tk.Button(control_frame, 
                 text="新游戏", 
                 command=self.new_game,
                 bg='#4CAF50', 
                 fg='white', 
                 relief='raised', 
                 padx=15).pack(side=tk.LEFT)
        
        # 难度选择
        tk.Label(control_frame, text="难度级别：", bg='#F0F0F0').pack(side=tk.LEFT, padx=10)
        self.level_var = tk.StringVar(value="中等")
        level_menu = ttk.Combobox(control_frame, 
                                 textvariable=self.level_var,
                                 values=["简单", "中等"], 
                                 state="readonly", 
                                 width=8)
        level_menu.pack(side=tk.LEFT)

    def create_game_board(self):
        """创建游戏棋盘区域"""
        board_frame = tk.Frame(self.window, bg='#FFFFFF')
        board_frame.pack(expand=True, fill=tk.BOTH, padx=20, pady=10)
        
        # 创建棋盘画布
        self.canvas = tk.Canvas(board_frame, 
                               width=650, 
                               height=650, 
                               bg='#F0D9B5',
                               highlightthickness=0)
        self.canvas.pack(expand=True)

    def init_game(self):
        """初始化游戏数据"""
        self.board_size = 15
        self.cell_size = 40
        self.offset = 20
        self.chess_board = [[0]*self.board_size for _ in range(self.board_size)]
        self.current_player = 1  # 1:玩家（黑棋） 2:AI（白棋）
        
        self.draw_board()
        self.canvas.bind("<Button-1>", self.player_move)

    def draw_board(self):
        """绘制棋盘"""
        self.canvas.delete("all")
        # 绘制棋盘线
        line_color = '#8B4513'
        for i in range(self.board_size):
            x = self.offset + i * self.cell_size
            self.canvas.create_line(x, self.offset, 
                                   x, self.offset + (self.board_size-1)*self.cell_size, 
                                   fill=line_color)
            self.canvas.create_line(self.offset, x,
                                   self.offset + (self.board_size-1)*self.cell_size, x,
                                   fill=line_color)
        
        # 绘制星位点
        star_points = [(3,3), (3,11), (11,3), (11,11), (7,7)]
        for x,y in star_points:
            cx = self.offset + x * self.cell_size
            cy = self.offset + y * self.cell_size
            self.canvas.create_oval(cx-4, cy-4, cx+4, cy+4, fill='black')

    def new_game(self):
        """开始新游戏"""
        self.canvas.delete("all")
        self.chess_board = [[0]*self.board_size for _ in range(self.board_size)]
        self.current_player = 1
        self.draw_board()

    def player_move(self, event):
        """处理玩家落子"""
        if self.current_player != 1:
            return
            
        x = round((event.x - self.offset) / self.cell_size)
        y = round((event.y - self.offset) / self.cell_size)
        
        if self.is_valid_move(x, y):
            self.place_chess(x, y, 1)
            if self.check_win(x, y, 1):
                self.game_over("玩家")
            else:
                self.current_player = 2
                self.window.after(500, self.ai_move)

    def ai_move(self):
        """AI回合"""
        level = self.level_var.get()
        if level == "简单":
            x, y = self.random_ai()
        else:
            x, y = self.smart_ai()
        
        if self.is_valid_move(x, y):
            self.place_chess(x, y, 2)
            if self.check_win(x, y, 2):
                self.game_over("电脑")
            else:
                self.current_player = 1

    def place_chess(self, x, y, player):
        """放置棋子"""
        # 棋子颜色设置
        color = '#333333' if player == 1 else '#FFFFFF'  # 黑/白
        outline = '#666666'  # 统一边框颜色
        
        cx = self.offset + x * self.cell_size
        cy = self.offset + y * self.cell_size
        
        # 绘制棋子主体
        self.canvas.create_oval(cx-15, cy-15, cx+15, cy+15,
                              fill=color, outline=outline, width=2)
        
        # 黑棋添加高光
        if player == 1:
            self.canvas.create_oval(cx-8, cy-8, cx-3, cy-3,
                                  fill='#FFFFFF', outline='')
        
        self.chess_board[x][y] = player
        
        # 播放落子音效
        self.checker_sound.play()

    def smart_ai(self):
        """智能AI决策"""
        best_score = -1
        candidates = []
        
        for x in range(self.board_size):
            for y in range(self.board_size):
                if self.chess_board[x][y] != 0:
                    continue
                
                # 计算进攻和防守评分
                attack = self.evaluate_position(x, y, 2)  # AI视角
                defend = self.evaluate_position(x, y, 1)  # 玩家视角
                score = max(attack, defend * 0.8)
                
                if score > best_score:
                    best_score = score
                    candidates = [(x,y)]
                elif score == best_score:
                    candidates.append((x,y))
        
        return random.choice(candidates) if candidates else self.random_ai()

    def evaluate_position(self, x, y, player):
        """评估位置价值"""
        directions = [(1,0), (0,1), (1,1), (1,-1)]
        total_score = 0
        
        for dx, dy in directions:
            line = []
            # 获取该方向上的9个连续点
            for step in range(-4, 5):
                nx = x + dx * step
                ny = y + dy * step
                if 0 <= nx < 15 and 0 <= ny < 15:
                    line.append(self.chess_board[nx][ny])
                else:
                    line.append(-1)  # 边界外
            
            # 分析所有可能的五连组合
            for i in range(5):
                segment = line[i:i+5]
                count = sum(1 for p in segment if p == player)
                empty = sum(1 for p in segment if p == 0)
                
                if count == 4 and empty == 1:  # 冲四
                    total_score += 2000
                elif count == 3 and empty == 2:  # 活三
                    total_score += 500
                elif count == 2 and empty == 3:  # 活二
                    total_score += 100
        
        return total_score

    def random_ai(self):
        """随机AI"""
        empty_spots = [(x,y) for x in range(15) for y in range(15) 
                      if self.chess_board[x][y] == 0]
        return random.choice(empty_spots) if empty_spots else (7,7)

    def is_valid_move(self, x, y):
        """验证落子有效性"""
        return (0 <= x < self.board_size 
                and 0 <= y < self.board_size 
                and self.chess_board[x][y] == 0)

    def check_win(self, x, y, player):
        """检查胜利条件"""
        directions = [(1,0), (0,1), (1,1), (1,-1)]
        
        for dx, dy in directions:
            count = 1
            # 向两个方向延伸检查
            for d in [1, -1]:
                step = 1
                while True:
                    nx = x + dx * step * d
                    ny = y + dy * step * d
                    if 0 <= nx < 15 and 0 <= ny < 15:
                        if self.chess_board[nx][ny] == player:
                            count += 1
                            step += 1
                        else:
                            break
                    else:
                        break
            if count >= 5:
                return True
        return False

    def game_over(self, winner):
        """处理游戏结束"""
        messagebox.showinfo("游戏结束", f"{winner} 获胜！")
        self.current_player = 0  # 禁用继续操作

if __name__ == "__main__":
    GobangAI()
